using GZ.Common.Data;
using Newtonsoft.Json;
using GZ.DB.Repository.wcs_hy;
using GZ.DB.Entity.wcs_hy;
using GZ.DB.IRepository.wcs_hy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Configuration;
using GZ.Projects.WCS_SVC;
using System.Net.NetworkInformation;
using GZ.Common.Code;

namespace GZ.Projects.WCS_SVC
{

	#region IC01.AGV作业任务操作
	/// <summary>
	/// wcs下发agv任务下发接口参数
	/// </summary>
	[Serializable]
	/*	00表示：位置编号
		01表示：物料批次号
		02表示：策略编号（含多个区域）如：第一个区域放不下, 可以放第二个区域
		03表示：货架编号，通过货架编号找到货架所在位置
		04表示：区域编号，在区域中查找可用位置
		05表示：仓位编号（叉车/CTU 专用）
		06表示：巷道编号
		07表示：容器编号
		08表示：巷道策略
		09表示：巷道区域
		10表示：巷道仓位
		11表示：输送线（机台）编号
		12表示：CTU 工作台（梳齿工作站）编号
		13表示：搬运巷道指定货架出库
	*/

	public class ToAgvOperateTask
	{
		public string reqCode; //请求编号

		//这里引入判空不显示字段
		[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
		public string taskType; //任务类型 0-普通 1-出库 2-入库 3-移库

		[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
		public string wbCode; //工作位

		[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
		public List<AgvStep> positionCodePaths; //取放货点位置

		[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
		public string podCode; //任务编号

		[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
		public string agvCode; //AGV编号

		public string taskCode; //任务编号
	}
	#endregion
	// 定义AGV步骤数据结构
	public class AgvStep
	{
		public string position_code { get; set; }
		public string position_type { get; set; }
	}

// 定义位置代码路径结构，匹配你的JSON格式
	public class PositionCodePath
	{
		public List<AgvStep> positionCodePath { get; set; }
	}
	/// <summary>
	/// agv与wcs交互的返回值
	/// </summary>
	[Serializable]
	public class wcsToAgvResponse
	{
		public string code;
		public string message;
		public string reqCode;
	}
	#region IC02.AGV作业任务上报
	/// <summary>
	/// agv上报wcs任务状态参数
	/// </summary>
	[Serializable]
	public class FromAgvCallBack
	{ 
		public string reqCode; //请求编号
		public string method; //方法名称
		public string taskType; //任务类型 0-普通 1-出库 2-入库 3-移库
		public string taskCode; //任务单号
		public string wbCode; //工作位
		public string podCode; //货架编号
	}	
	#endregion
	
	public class WCSTOAGV
	{
		private static string _url = string.Empty;
		public bool ToAgvOperateTask(ToAgvOperateTask toAgvOperateTask,string direction, out string message)
		{
			string msg = $"\r\n[wcs下发任务信息至AGV：Start{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
			message = null;
			//wcsToAgvResponse response = new wcsToAgvResponse();
			try
			{
				switch (direction)
				{
					case "1":
						//下发任务
						_url = ConfigurationManager.AppSettings["createAgvTask"];
						break;
					case "2":
						//继续任务
						_url = ConfigurationManager.AppSettings["continueAgvTask"]; 
						break;
					case "3":
						//取消任务
						_url = ConfigurationManager.AppSettings["cancelAgvTask"]; 
						break;
					default:
						message = "未知操作类型";
						return false;
				}
				//设置隐藏字段
				string input = JsonConvert.SerializeObject(toAgvOperateTask, Formatting.None, new JsonSerializerSettings
				{
					NullValueHandling = NullValueHandling.Ignore
				});
				msg += $"\r\n\t下发json:[{input}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				//string json = new HttpClient().Call(input, url, out errorMsg);
				string json = new HttpClient().Call("POST",input, _url, out message);
				msg += $"\r\n\t收到回复json:[{json}]{DateTime.Now:yyyy/MM/dd HH:mm:ss:fff}";
				wcsToAgvResponse response = Json.ToObject<wcsToAgvResponse>(json);
				//AGV接口文档中 0 失败 1成功
				if (response != null && response.code == "0")
				{
					message = json;
					return true;
				}
				else
				{
					message = json;
					return false;
				}
			}
			catch (Exception ex)
			{
				msg += ex.Message;
				message = ex.Message;
				return false;
			}
			finally
			{
				msg = msg.Replace('\'', '\"');
				Conn.YBLog.Info(1, $"WCS下发任务至AGV ", 1, msg);
			}
		}
	}


	public static class ToAgvHandle
	{
		/// <summary>
		/// 任务回复 ToWmsResponseOrderData JSON 文本
		/// </summary>
		private static string BuildResponseToAgv( string code, string message , string reqCode = null)
		{
			// 截断 msg 到 256 字符,系统异常返回值太长，需要截断
			if (!string.IsNullOrEmpty(message) && message.Length > 64)
				message = message.Substring(0, 64);
			var resp = new wcsToAgvResponse
			{
				code = code,
				message = message,
				reqCode = reqCode
			};
			return JsonConvert.SerializeObject(resp);
		}
		
		/// <summary>
		/// IC01.AGV任务状态获取
		/// </summary>
		/// <param name="requestJson"></param>
		/// <returns></returns>
		public static string GetAgvCallBack(string requestJson)
		{
			//string respJson = string.Empty;
			//1-任务开始，2-取货中，3-取货完成，4-放货中，5-放货完成，6-任务取消，7-异常
			try
			{
				var request = JsonConvert.DeserializeObject<FromAgvCallBack>(requestJson);
				//1. 检查请求参数是否为空
				if (request == null)
				{
					return BuildResponseToAgv("-1", "请求参数为空");
				}
				else
				{
					if (string.IsNullOrEmpty(request.reqCode))
					{
						return BuildResponseToAgv("-1", "请求编号不可为空");
					}

					if (string.IsNullOrEmpty(request.method) || string.IsNullOrEmpty(request.taskCode))
					{
						return BuildResponseToAgv("-1", "请求任务编号或方法不可为空", request.reqCode);
					}
					AutoScanApp auto = new AutoScanApp();
					//2.根据任务编号查询任务
					AgvTaskRepository agvTaskRepository = new AgvTaskRepository();
					AgvTaskEntity agvTask = agvTaskRepository.FindEntity(t => t.task_no == request.taskCode);
					if (agvTask == null)
					{
						return BuildResponseToAgv("-1", "请求的任务号业务数据库中任务不存在",request.reqCode);
					}
					else
					{
						var agvTaskStep = new AgvCarryStepRepository().FindEntity(t => t.task_type == request.taskType && t.step_method == request.method);
						//3.步骤模板是否正确配置符合约定
						if(agvTaskStep == null)
						{
							return BuildResponseToAgv("-1", "请求的任务步骤不存在", request.reqCode);
						}
						//4.检查步骤编号是否重复上报
						if (agvTaskStep.step_no == agvTask.step_no)
						{
							return BuildResponseToAgv("-1", "重复的报告处理",request.reqCode);
						}
						//5. 检查当前位置并判断是否记绑通知wms
						switch (agvTaskStep.position_code)
						{
							case  "[FRM_POS]": 
							case "[TO_POS]": break;
							// 需要询问线体是否可取,根据任务的任务起始位置
							case "[FRM_POS_INREQ]":
								if (agvTask.frm_pos.StartsWith("10"))
								{
									agvTask.task_condition = "TPPLC_1.PLC_CANIN_" + agvTask.frm_pos;
								}
								if (agvTask.frm_pos.StartsWith("20"))
								{
									agvTask.task_condition = "TPPLC_2.PLC_CANIN_" + agvTask.frm_pos;
								}
								agvTask.req_type = "2";
								agvTask.LastUpdatedTime = DateTime.Now;
								var mainTaskFrm = new MainMissionRepository().FindEntity(t=> t.task_no == agvTask.task_no);
								if (mainTaskFrm == null)
								{
									return BuildResponseToAgv("-1", "任务主表不存在", request.reqCode);
								}
								mainTaskFrm.InteStationNo = agvTask.frm_pos;
								bool res = auto.UpdateAgvAndMainTask(agvTask, mainTaskFrm,out string err);
								if (!res)
								{
									return BuildResponseToAgv("-1", err, request.reqCode);
								}
								break;
							case "[TO_POS_INREQ]":
								if (agvTask.to_pos.StartsWith("10"))
								{
									agvTask.task_condition = "TPPLC_1.PLC_CANOUT_" + agvTask.to_pos;
								}
								if (agvTask.to_pos.StartsWith("20"))
								{
									agvTask.task_condition = "TPPLC_2.PLC_CANOUT_" + agvTask.to_pos;
								}
								agvTask.req_type = "2";
								agvTask.LastUpdatedTime = DateTime.Now;
								var mainTaskTo = new MainMissionRepository().FindEntity(t=> t.task_no == agvTask.task_no);
								if (mainTaskTo == null)
								{
									return BuildResponseToAgv("-1", "任务主表不存在", request.reqCode);
								}
								mainTaskTo.InteStationNo = agvTask.to_pos;
								bool res1 = auto.UpdateAgvAndMainTask(agvTask, mainTaskTo,out string err1);
								if (!res1)
								{
									return BuildResponseToAgv("-1", err1, request.reqCode);
								}
								break;

						}
						return BuildResponseToAgv("0", "success",request.reqCode);
					}
				}
			}
			catch (Exception ex)
			{
				return BuildResponseToAgv("-1", ex.Message);
			}
		
		}

	}
}